soundtrack object
The soundtrack object is stored in soundtrack.bgt in the BGT include directory. Building upon the BGT tone generator, the soundtrack object attempts to give you more music for less code.
soundtrack()
Parameters:
None.
Remarks:
Using the soundtrack object, you create music by adding channels to a song. A channel is described by a sequence of commands. Note that the command sequence contains no spaces---it is simply a string of commands as defined below.
Setting the octave
Use the o command followed by a number to set the octave for subsequent notes. Valid octaves are 1 to 6, so o1 through o6 are valid octave commands. The default octave starts out as 4.
Setting the default length
Use the l command followed by a number to set the default length for subsequent notes. A note may provide its own length, but those that don't will get the default length. Lengths are specified by how many of them would fit into a whole note. For example, 1 is a whole note, 2 is a half note, and 16 is a 16th note. Any whole number from 1 to 64 is allowed. For example, 24 is a length that would fit three times into an 8th note. The default length starts out as 4 (meaning quarter notes).
Increasing or decreasing the octave
The < and > commands provide convenient shortcuts for increasing or decreasing the octave by one. The > command increases the octave if possible, and the < command decreases it if possible.
Selecting the instrument
Use the @ command followed by a number to select the instrument for subsequent notes. Valid instruments are @1 (sawtooth), @2 (square), @3 (sine) and @4 (triangle). The instrument starts out as @1 (sawtooth).
Setting the quantization
Quantization determines how much of the note will actually be heard. Use the q command followed by a number between 1 and 100 to set the quantization for subsequent notes. A quantization of 8 means the entire note will be heard while, for example, a quantization of 4 means that only the first half of the note will be heard whereas the second half will be silenced. Use quantizations greater than 8 to make a note last beyond its notational end. The quantization starts out at 8.
Setting the tempo
Use the t command followed by a number to set the tempo for subsequent notes. The tempo is measured in quarter notes per minute, and valid tempi are numbers between 60 and 240. The tempo starts out as 120. You may have as many tempo changes as you like, and it is perfectly valid to have different channels play at different tempi although the result might not be to your liking.
Setting the attack
Attack determines how long the note will rise in volume until it reaches its maximum. Use the a command followed by a number to set the attack for subsequent notes. Valid attack values are 0 to 100. 100 means that the note will take a second to reach its maximum volume, while 0 means that the note will start out at its maximum volume. The attack value starts out as 1.
Setting the release
Release determines how long the note will take to fade from its maximum volume to silence. Use the r command to set the release for subsequent notes. Valid release values are 0 to 100. 100 means that the note will take a second to fade, while 0 means it will go directly to silence as if cut off. Note that having a note with 0 release followed by a note with 0 attack may create a clicking noise. This is not a bug but simply means the generator is doing what it should. The release value starts out as 1.
Generating a pause
Use the p command followed by a number to insert a pause, or rest, into your channel. The number follows the same rules as that used in the l command, so p1 will create a whole rest, p4 will create a quarter rest, etc.
Setting the volume
Use v followed by a number between 0 and 100 to set the volume. 100 is loudest while 0 is silent. The volume starts out at 100.
Transposition
Use u followed by a number to shift subsequent notes up the given number of semitones. Use d followed by a number to shift subsequent notes down the given number of semitones. Use the n command to specify that subsequent notes should no longer be transposed. The u and d commands accept numbers from 1 to 11. These three commands are best remembered as u for up, d for down, and n for normal.
Generating notes
Use one of the uppercase letters C, D, E, F, G, A, B to insert a corresponding note. To sharpen the note, put a + after it, and to flatten the note, put a - after it.
If you leave it at that, the note will get the default length. To change the length for just this single note, put a number directly after it. For example, E-2 is a half E flat.
Finally, you can put a . after the whole thing to get a dotted note. A dotted note is simply a note with its length increased by half of what it was. For example, F2. is a half F dotted, meaning an F the length of three quarter notes.
Generating chords
To generate chords, i.e. simultaneous notes, connect them with an & sign, like so:
C&E&G
This would generate a C major chord in the current channel.
It is valid to connect notes in this way even if they are of different lengths. Technically, the & operator only makes sure that all the notes it connects start at the same time. Consider the following:
l1C&E&G&>l8CDEFGAG4
In terms of a piano, this is a left hand playing a C major chord while the right hand, one octave higher, plays a little cheery melody.
Repetitions
To repeat a sequence of commands a given number of times, enclose the sequence in brackets and put a number from 2 to 100 directly after the closing bracket, like so:
[CDE]3
This would be equivalent to:
CDECDECDE
Any sequence of commands is valid between the brackets. For example, to shift down 3 octaves you can write:
[<]3
Repetitions can even be nested. For example:
[[CDE]3[EFG]3]2
is equivalent to:
CDECDECDEEFGEFGEFGCDECDECDEEFGEFGEFG
Example:
// Write a song.
#include "soundtrack.bgt"
void main()
{
soundtrack s;
string preamble = "t140u6";
string chords1 = "@1v97l2a8r100q12[C&E&G]2[<B&>E&G]2[<B-&>E&G]2[<A&>D&F]2<F+&A&B&>D<A-&B&>D&E<A&>C&E<G&>C&E<E&G&>C<D&F+&>C<F&G&>C&D<F&G&B&>D";
string chords2 = "[<B&>D&G]2[C&E&G]2q20<B4&>D4&B4C8&E8&>C8<<l4B&>D&B<A&>C&Aq12l2<G&B&>Gp8<G&B&>C&G<B&>D&G<B&>D&F<B&>D&G<G&>C&E";
string chords3 = "<G&>C&E<F+&>C&D<F&>C&D<F&B&>D";
string chords4 = "[<A&>C&F]3<G&B&>F<G&>C&El8q8r10<B-&>C&Gl4<A-&>C&Fl1<G&>C&Ep8l4<A-&>C&E<A-&>C&Dp4l1<E&G&>C";
string chords = chords1 + chords1 + chords2 + chords3 + chords2 + chords4;
string bass1 = "@3r100C2.CC2.CC2.CC2.C<B2>E2<A2.A>D2.D<G2.";
string bass2 = "E2.E<A2.A>F2.FE2<A2>F2<B2>E2<A2>";
string bass3 = "D2.D<G2.>F";
string bass4 = "D2.D4<G2.G>C1C1C4<G4p4C1";
string bass = bass1 + "G>" + bass1 + ">F" + bass2 + bass3 + bass2 + bass4;
string melody1 = "@2a10r10E2.p4E2.p4EE8FCD2.p4p8DD8E4.<B8>C4.DC<BA2p8>E.";
string melody2 = "l4G2.p4G2.p4B>C8<BAG2.p4p8B8B8>C8<B4.A8G4.>D8C4.<";
string melody3 = "E8E2.p8D8CD2A4.";
string melody4 = "l4EEF8F4.GA2B2>C1.";
string melody = melody1 + "D2.p4" + melody1 + "D2p8A4." + melody2 + melody3 + melody2 + melody4;
s.add_channel(preamble + "o3" + bass);
s.add_channel(preamble + "o2" + bass);
s.add_channel(preamble + chords);
s.add_channel(preamble + melody);
s.add_channel(preamble + "o5v90" + melody);
s.write("song4.wav");
}